<template>
  <el-form :model="props.params" ref="formRef" v-bind="{ ...attrs }">
    <el-row :gutter="props.gutter">
      <el-col
        v-for="(form, index) in props.forms"
        :key="form.prop"
        :span="form.span || 24"
        :class="form.class"
        v-show="!form.hidden"
        style="margin-bottom: 10px"
      >
        <el-form-item
          :key="index"
          :prop="form.prop"
          v-if="!form.hidden"
          :label="form.label"
          :rules="form.rules || []"
          v-bind="{ ...form }"
        >
          <div slot="label" v-if="form.slotHeaderName" class="slotHeaderName">
            <slot :name="form.slotHeaderName" :params="props.params" :form="form" />
          </div>
          <template v-if="form.slotName">
            <slot :name="form.slotName" :params="props.params" :form="form" />
          </template>
          <template v-else>
            <el-input
              v-if="form.itemType === 'input' || form.itemType === undefined"
              :style="form.itemWidth ? `width: ${form.itemWidth}` : 'width:100%'"
              :clearable="form.clearable || true"
              :placeholder="form.placeholder || '请输入'"
              v-bind="{ ...form }"
              @clear="
                () => {
                  form.clearInput ? form.clearInput({ form, params: props.params }) : '';
                }
              "
              @input="
                (value) => {
                  form.input ? form.input({ value, params: props.params, form, index }) : '';
                }
              "
              @change="
                (value) => {
                  form.changeInput
                    ? form.changeInput({ value, params: props.params, form, index })
                    : '';
                }
              "
              v-model="props.params[form.prop]"
            ></el-input>
            <el-input
              v-if="form.itemType === 'textarea'"
              v-model="props.params[form.prop]"
              type="textarea"
              :style="form.itemWidth ? `width: ${form.itemWidth}` : 'width:100%'"
              v-bind="{ ...form }"
              @clear="
                () => {
                  form.clearInput ? form.clearInput({ form, params: props.params }) : '';
                }
              "
              @change="
                (value) => {
                  form.changeInput
                    ? form.changeInput({ value, params: props.params, form, index })
                    : '';
                }
              "
            >
            </el-input>

            <el-select
              v-else-if="form.itemType === 'select'"
              :clearable="form.clearable || true"
              v-model="props.params[form.prop]"
              :style="form.itemWidth ? `width: ${form.itemWidth}` : 'width:100%'"
              :filterable="form.filterable || true"
              :placeholder="form.placeholder || '请选择'"
              v-bind="{ ...form }"
              @clear="
                () => {
                  form.clearSelect ? form.clearSelect({ form, params: props.params }) : '';
                }
              "
              @change="
                (value) => {
                  form.changeSelect
                    ? form.changeSelect({ value, params: props.params, form, index })
                    : '';
                }
              "
              @visibleChange="
                (value) => {
                  form.visibleChange
                    ? form.visibleChange({ value, params: props.params, form, index })
                    : '';
                }
              "
              @removeTag="
                (value) => {
                  form.removeTagSelect
                    ? form.removeTagSelect({ value, params: props.params, form, index })
                    : '';
                }
              "
            >
              <el-option
                v-for="(option, selectIndex) in form.options"
                :key="selectIndex + option.value"
                :value="option.value"
                :label="option.label"
                v-bind="{ ...option }"
                @click="
                  (value) => {
                    form.clickSelect
                      ? form.clickSelect({ value: option.value, params: props.params, form, index })
                      : '';
                  }
                "
              >
              </el-option>
              <slot :name="form.selectOptionSlotName" :params="form.params" :form="form"></slot>
            </el-select>
            <el-cascader
              v-else-if="form.itemType === 'cascader'"
              v-model="props.params[form.prop]"
              :options="form.options || []"
              :style="form.itemWidth ? `width: ${form.itemWidth}` : 'width:100%'"
              :clearable="form.clearable || true"
              :filterable="form.filterable || true"
              v-bind="form"
              @change="
                (value) => {
                  form.changeCascader
                    ? form.changeCascader({ value, params: props.params, form, index })
                    : '';
                }
              "
              @removeTag="
                (value) => {
                  form.removeTagCascader
                    ? form.removeTagCascader({ value, params: props.params, form, index })
                    : '';
                }
              "
              @expandChange="
                (value) => {
                  form.expandChangeCascader
                    ? form.expandChangeCascader({ value, params: props.params, form, index })
                    : '';
                }
              "
            >
              <template #default="{ node, data }">
                <span
                  class="cascader"
                  @click="
                    (e) => {
                      form.clickCascader
                        ? form.clickCascader({ params: props.params, form, index, node, data })
                        : '';
                    }
                  "
                >
                  <span>{{ data[form.props.label] }}</span>
                  <span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
                </span>
              </template>
            </el-cascader>
            <el-cascader
              v-else-if="form.itemType === 'cascade'"
              v-model="props.params[form.prop]"
              :clearable="form.clearable || true"
              :filterable="form.filterable || true"
              v-bind="form"
              @visible-change="
                (value) => {
                  form.visibleChange
                    ? form.visibleChange({ value, params: props.params, form, index })
                    : '';
                }
              "
              @blur="
                (value) => {
                  form.blur ? form.blur({ value, params: props.params, form, index }) : '';
                }
              "
            >
            </el-cascader>
            <el-switch
              v-else-if="form.itemType === 'switch'"
              v-model="props.params[form.prop]"
              :style="form.itemWidth ? `width: ${form.itemWidth}` : 'width:100%'"
              v-bind="{ ...form }"
              @change="
                (value) => {
                  form.changeSwitch
                    ? form.changeSwitch({ value, params: props.params, form, index })
                    : '';
                }
              "
            ></el-switch>
            <el-slider
              v-else-if="form.itemType === 'slider'"
              v-model="props.params[form.prop]"
              :style="form.itemWidth ? `width: ${form.itemWidth}` : 'width:100%'"
              v-bind="{ ...form }"
              @change="
                (value) => {
                  form.changeSlider
                    ? form.changeSlider({ value, params: props.params, form, index })
                    : '';
                }
              "
              @input="
                (value) => {
                  form.inputSlider
                    ? form.inputSlider({ value, params: props.params, form, index })
                    : '';
                }
              "
            ></el-slider>
            <el-date-picker
              v-else-if="form.itemType === 'date'"
              v-model="props.params[form.prop]"
              v-bind="{ ...form }"
              :style="form.itemWidth ? `width: ${form.itemWidth}` : 'width:100%'"
              @change="
                (value) => {
                  form.changeDate
                    ? form.changeDate({ value, params: props.params, form, index })
                    : '';
                }
              "
            ></el-date-picker>
            <el-time-picker
              v-else-if="form.itemType === 'time'"
              v-model="props.params[form.prop]"
              v-bind="{ ...form }"
              :style="form.itemWidth ? `width: ${form.itemWidth}` : 'width:100%'"
              @change="
                (value) => {
                  form.changeTime
                    ? form.changeTime({ value, params: props.params, form, index })
                    : '';
                }
              "
            ></el-time-picker>
            <el-transfer
              v-else-if="form.itemType === 'transfer'"
              v-model="props.params[form.prop]"
              :data="form.options"
              v-bind="{ ...form }"
              :style="form.itemWidth ? `width: ${form.itemWidth}` : 'width:100%'"
              @change="
                (value) => {
                  form.changeTransfer
                    ? form.changeTransfer({ value, params: props.params, form, index })
                    : '';
                }
              "
            >
            </el-transfer>
            <el-radio-group
              v-else-if="form.itemType === 'radio'"
              v-model="props.params[form.prop]"
              v-bind="{ ...form }"
              :style="form.itemWidth ? `width: ${form.itemWidth}` : 'width:100%'"
              @change="
                (value) => {
                  form.changeRadio
                    ? form.changeRadio({ value, params: props.params, form, index })
                    : '';
                }
              "
            >
              <el-radio
                v-for="(radio, radioIndex) in form.options"
                :label="radio.value"
                :key="radioIndex"
                >{{ radio.label }}</el-radio
              >
            </el-radio-group>
            <div v-else-if="form.itemType === 'checkbox'">
              <el-checkbox
                v-model="checkAll"
                :indeterminate="isIndeterminate"
                @change="handleCheckAllChange"
                v-if="props.isCheckedAll"
                >全部</el-checkbox
              >
              <el-checkbox-group
                v-model="props.params[form.prop]"
                v-bind="{ ...form }"
                :style="form.itemWidth ? `width: ${form.itemWidth}` : 'width:100%'"
                @change="
                  (value) => {
                    form.changeCheckbox
                      ? form.changeCheckbox({ value, params: props.params, form, index })
                      : '';
                  }
                "
              >
                <el-checkbox
                  v-for="(checkbox, checkboxIndex) in form.options"
                  :label="checkbox.value"
                  :key="checkbox.value + checkboxIndex"
                  name="type"
                  >{{ checkbox.label }}</el-checkbox
                >
              </el-checkbox-group>
            </div>

            <el-upload
              v-else-if="form.itemType === 'upload'"
              v-model:file-list="props.params[form.prop]"
              v-bind="form"
              class="w-full upload-demo"
              :drag="true"
              action="#"
              :auto-upload="false"
              :limit="form.fileLimit ?? 100"
            >
              <el-icon :size="48"> </el-icon>
              <div class="el-upload__text">
                {{ form.tipText ?? "请点击或者拖动文件到该区域来上传" }}
                <br />
              </div>
              <template #tip>
                <div class="el-upload__tip"></div>
              </template>
            </el-upload>
            <div
              v-else-if="form.itemType === 'button'"
              v-bind="{ ...form }"
              style="display: flex"
              :style="form.center ? { justifyContent: 'center' } : ''"
            >
              <el-button
                v-for="(buttonItem, buttonIndex) in form.options"
                :key="buttonItem.id"
                :style="form.itemWidth ? `width: ${form.itemWidth}` : 'width:100%'"
                v-bind="{ ...buttonItem }"
                @click="
                  form.click
                    ? form.click()
                    : onButtonClick(formRef, props.params, buttonIndex, buttonItem)
                "
              >
                <span
                  v-if="buttonItem.icon == 'ArrowDown'"
                  style="display: inline-block; vertical-align: middle"
                  ><el-icon><ArrowDown /></el-icon
                ></span>
                <span
                  v-if="buttonItem.icon == 'ArrowUp'"
                  style="display: inline-block; vertical-align: middle"
                  ><el-icon><ArrowUp /></el-icon
                ></span>
                {{ buttonItem.label }}</el-button
              >
            </div>
            <div
              v-else-if="form.itemType === 'fixedButton'"
              v-bind="{ ...form }"
              class="flex fixed bottom-10px"
            >
              <el-button
                v-for="(buttonItem, buttonIndex) in form.options"
                :key="buttonItem.id"
                :style="form.itemWidth ? `width: ${form.itemWidth}` : 'width:100%'"
                v-bind="{ ...buttonItem }"
                @click="onButtonClick(formRef, props.params, buttonIndex, buttonItem)"
                >{{ buttonItem.label }}</el-button
              >
            </div>
            <div v-else-if="form.itemType === 'span'" v-bind="{ ...form }">
              <span>{{ form.prop }}</span>
            </div>
            <div v-else-if="form.appendTip" class="text-[#999] leading-20px">
              {{ form.appendTip }}
            </div>
          </template>
        </el-form-item>
      </el-col>
      <el-col v-if="props.isTip">
        <div class="dialog-tip">
          <div>
            <p>特别提示</p>
            <p class="brcss">{{ state.tipText }}<br /></p>
          </div>
        </div>
      </el-col>
      <el-col :span="24" class="center" v-if="props.buttonConfig.showSubmitButton">
        <el-form-item label="" class="dialog-footer" label-width="0">
          <el-button
            v-for="(buttonItem, buttonIndex) in props.buttonConfig.options"
            :key="buttonItem.id"
            v-bind="{ ...buttonItem }"
            @click="onButtonClick(formRef, props.params, buttonIndex, buttonItem)"
            >{{ buttonItem.label }}</el-button
          >
        </el-form-item>
      </el-col>
    </el-row>
  </el-form>
</template>

<script setup>
import {
  defineProps,
  defineEmits,
  ref,
  nextTick,
  reactive,
  onMounted,
  useAttrs,
  defineExpose,
} from "vue";
const checkAll = ref(false);
const isIndeterminate = ref(true);

const formRef = ref(null);
const attrs = useAttrs(); //外部传进的额外属性

const props = defineProps({
  forms: {
    type: Array,
    default: () => [],
  },
  params: {
    type: Object,
    default: () => {},
  },
  gutter: {
    type: Number,
    default: 10,
  },
  buttonConfig: {
    type: Object,
    default: () => ({
      showSubmitButton: false,
      submitText: "提交",
      resetText: "重置",
    }),
  },
  loadMoreNameData: {
    type: Function,
    default: () => {
      return () => {};
    },
  },
  isCheckedAll: {
    type: Boolean,
    default: false,
  },
  isTip: {
    type: Boolean,
    default: false,
  },
  tipText: {
    type: String,
    default: "selfDefine",
  },
});
const state = reactive({
  tipText: props.tipText,
});
const emits = defineEmits(["onSubmit", "onReset", "onOther", "handleCheckAllChange", "onShowMore"]);
const onButtonClick = async (formEl, params, index, buttonItem) => {
  if (buttonItem.id === 1) {
    if (!formEl) return;
    await formEl.validate((valid, fields) => {
      if (valid) {
        emits("onSubmit", { params, index, buttonItem });
        // formEl.resetFields()
      } else {
        console.log("error submit!", fields);
      }
    });
  } else if (buttonItem.id === 0) {
    if (!formEl) return;
    formEl.resetFields();
    emits("onReset", { params, index, buttonItem });
  } else if (buttonItem.id === 2) {
    emits("onShowMore");
  }
};
const handleCheckAllChange = (value) => {
  emits("handleCheckAllChange", { value: checkAll.value });
  // checkedCities.value = val ? cities : []
  // emits('handleCheckAllChange',val)
  isIndeterminate.value = false;
};
defineExpose({
  onButtonClick,
  formRef,
  checkAll,
  isIndeterminate,
});
</script>

<style lang="scss" scoped></style>
